The present invention relates to the field of bytecode verification, and, more particularly, to intelligently reusing local variables to reduce extraneous class loads during bytecode verification.
Many programming languages, such as JAVA and SMALLTALK, generate bytecode from user-input software code for use by a bytecode interpreter such as the JAVA VIRTUAL MACHINE (JVM). Bytecode is an instruction set that contains the encoded results of the parsing and semantic analysis of the user-entered program code objects. Prior to execution by the bytecode interpreter, the bytecode is verified to ensure that the structural and static constraints of the bytecode interpreter are met. Verification is a compiler independent process that checks that a class satisfies the structural and static constraints of the computing space (e.g., a JVM) within which the bytecode executes.
A data-flow verification process can perform symbolic execution of the bytecode of each method and creates intermediate data known as a stack maps. These maps are merged at data-flow join points. The merging of local variables in a method requires that incompatible local variables be merged to “Top,” which is an indication that the local variable is unusable. That is, if Local Variable—1 contains an int on one execution path and if Local Variable—1 contains a java/lang/String on another path, then the resulting merge entry will be “Top”. This makes the local variable unusable until it has been loaded with a new variable.
Verification can often merge a local variable slot containing different classes. These classes are merged by the verifier in an attempt to identify the least common super-class. Many times, the merges will be valid and loading each class along with its full hierarchy is required. For instance, class/class mergers where each class is different and neither is JAVA/LANG/OBJECT will result in loading the complete hierarchy for both object types. Compiler optimizations often cause unnecessary merges by reusing a local variable memory store for variables that have non-overlapping scopes on different execution paths. These unnecessary class/class merges negatively affect the application start-up and memory usage.
Attempts at overcoming this problem have had a limited effect upon the verification process. One solution employed by the J9 Virtual Machine detects the non-trivial merge of local variables and performs a forward walk through the bytecode to check the future liveliness of the local variable slot to see if it is ever read again before being over-written. While helpful, this solution incurs additional overhead when determining the future liveliness of the local variable slot.